package com.wtwd.campus.service.impl;


import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.constant.DeviceAppFlagEnum;
import com.wtwd.campus.constant.UploadAppFileTypeEnum;
import com.wtwd.campus.constant.UploadAppTypeEnum;
import com.wtwd.campus.dao.DeviceAppMapper;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.hxy.service.CommandRecordService;
import com.wtwd.campus.model.dto.AppDisableTimeDto;
import com.wtwd.campus.model.dto.QueryAppDisAbleStateDto;
import com.wtwd.campus.model.vo.AuthDeviceIsSupportAppVo;
import com.wtwd.campus.model.vo.QueryDeviceAppVo;
import com.wtwd.campus.service.*;
import com.wtwd.campus.utils.CommandSendUtils;
import com.wtwd.campus.vcom.utils.CommandNumberUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mjy
 * @since 2022-12-12
 */
@Service
public class DeviceAppServiceImpl extends ServiceImpl<DeviceAppMapper, DeviceApp> implements DeviceAppService {

    @Resource
    private DeviceAppMapper deviceAppMapper;

    @Resource
    private AppDisableTimeService appDisableTimeService;

    @Resource
    private DeviceInfoService deviceInfoService;

    @Resource
    private DeviceFlagService deviceFlagService;

    @Resource
    private CommandSendUtils commandSendUtils;

    @Resource
    private RedisService redisService;

    @Resource
    private CommandRecordService commandRecordService;

    @Value("${file.http}")
    private String fileHttp;

    @Value("${app.upload.file}")
    private String appUploadFile;

    @Override
    public boolean dealUpLoadAppData(Integer deviceId, List<MqAppInfo> appInfos, int type) {
        if (deviceId == null || appInfos == null || appInfos.size() == 0) {
            return false;
        }
        if (UploadAppTypeEnum.ALL.getType() == type) {
            List<DeviceApp> deviceApps = new ArrayList<>();
            for (MqAppInfo appInfo : appInfos) {
                DeviceApp deviceApp = new DeviceApp();
                deviceApp.setDeviceId(deviceId);
                deviceApp.setName(appInfo.getAppName());
                deviceApp.setCreateTime(new Date().getTime());
                deviceApp.setUpdateTime(new Date().getTime());
                deviceApp.setType(appInfo.getAppType());
                deviceApp.setPackageName(appInfo.getPackageName());
                deviceApps.add(deviceApp);
            }
            return batchInsertOrUpdate(deviceApps);
        } else if (UploadAppTypeEnum.ADD.getType() == type) {//增加操作,设备端可能会重复上传,故只能做插入或更新
            List<DeviceApp> deviceApps = new ArrayList<>();
            for (MqAppInfo appInfo : appInfos) {
                DeviceApp deviceApp = new DeviceApp();
                deviceApp.setDeviceId(deviceId);
                deviceApp.setName(appInfo.getAppName());
                deviceApp.setType(appInfo.getAppType());
                deviceApp.setCreateTime(new Date().getTime());
                deviceApp.setUpdateTime(new Date().getTime());
                deviceApp.setPackageName(appInfo.getPackageName());
                deviceApps.add(deviceApp);
            }
            return batchInsertOrUpdate(deviceApps);
        } else if (UploadAppTypeEnum.DELETE.getType() == type) {
            List<DeleteDeviceAppDto> deleteDeviceAppDtos = new ArrayList<>();
            for (MqAppInfo appInfo : appInfos) {
                DeleteDeviceAppDto deleteDeviceAppDto = new DeleteDeviceAppDto();
                deleteDeviceAppDto.setDeviceId(deviceId);
                deleteDeviceAppDto.setPackageName(appInfo.getPackageName());
                deleteDeviceAppDtos.add(deleteDeviceAppDto);
            }
            return batchDelete(deleteDeviceAppDtos);
        }
        return false;
    }

    @Override
    public boolean batchInsertOrUpdate(List<DeviceApp> deviceApps) {
        if (deviceApps == null || deviceApps.size() == 0) {
            return false;
        }
        return deviceAppMapper.batchInsertOrUpdate(deviceApps);
    }

    @Override
    public boolean batchDelete(List<DeleteDeviceAppDto> deleteDeviceAppDtos) {
        if (deleteDeviceAppDtos == null || deleteDeviceAppDtos.size() == 0) {
            return false;
        }
        return deviceAppMapper.batchDelete(deleteDeviceAppDtos);
    }

    @Override
    public boolean updateAppDisableFlag(Integer deviceId, String packageName, int flag) {
        return deviceAppMapper.updateAppDisableFlag(deviceId, packageName, flag) > 0 ? true : false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean dealAppDisable(Integer deviceId, String packageName, int flag, List<MqAppDisableTime> mqAppDisableTimes) {
        boolean rest = updateAppDisableFlag(deviceId, packageName, flag);
        appDisableTimeService.synchronousData(deviceId, packageName, mqAppDisableTimes);
        return rest;
    }

    @Override
    public AuthDeviceIsSupportAppVo authDeviceIsSupportApp(String imei) {
        DeviceInfo deviceInfo = deviceInfoService.getDeviceByImei(imei);
        AuthDeviceIsSupportAppVo authDeviceIsSupportAppVo = new AuthDeviceIsSupportAppVo();
        if (deviceInfo == null) {
            authDeviceIsSupportAppVo.setRespCode(RespCode.DEVICE_NOT_FOUND);
            return authDeviceIsSupportAppVo;
        }
        if (!SUPPORT.equals(deviceInfo.getSupportPort())) {
            authDeviceIsSupportAppVo.setRespCode(RespCode.DEVICE_NOT_SUPPORT);
            authDeviceIsSupportAppVo.setDeviceInfo(deviceInfo);
            return authDeviceIsSupportAppVo;
        }
        authDeviceIsSupportAppVo.setRespCode(RespCode.SUCCESS);
        authDeviceIsSupportAppVo.setDeviceInfo(deviceInfo);
        return authDeviceIsSupportAppVo;
    }

    @Override
    public List<QueryDeviceAppVo> queryDeviceAppByDeviceId(Integer deviceId) {
        List<QueryDeviceAppVo> queryDeviceAppVos = deviceAppMapper.queryDeviceAppByDeviceId(deviceId, UploadAppFileTypeEnum.APP_IMAGE.getType());
        queryDeviceAppVos.stream().forEach(e -> {
            if(StringUtils.isNotBlank(e.getFilePath())){
                e.setFilePath(fileHttp.concat(appUploadFile).concat(e.getFilePath()));
            }
        });
        return deviceAppMapper.queryDeviceAppByDeviceId(deviceId, UploadAppFileTypeEnum.APP_IMAGE.getType());
    }

    @Override
    public boolean appInstallationSwitch(DeviceInfo deviceInfo, Integer flag) {
        if (deviceInfo == null) {
            return false;
        }
        deleteCacheCmd(deviceInfo.getImei(), Constants.APP_INSTALLATION);
        boolean rest = deviceFlagService.setAppInstallationFlag(deviceInfo.getDeviceId(), DeviceAppFlagEnum.getDeviceAppFlagEnum(flag).getStayState());
        if (rest) {
            boolean online = commandSendUtils.deviceOnline(deviceInfo.getImei());
            MqAppInstallationSwitch mqAppInstallationSwitch = new MqAppInstallationSwitch();
            mqAppInstallationSwitch.setImei(deviceInfo.getImei());
            mqAppInstallationSwitch.setCommandNumber(CommandNumberUtils.generateCommandNumber(redisService, deviceInfo.getImei()));
            mqAppInstallationSwitch.setOnOff(flag);
            commandSendUtils.appInstallationSwitch(mqAppInstallationSwitch, online, Constants.WX_COMMAND_USER_ID, false);
        }
        return rest;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteCacheCmd(String imei, String cmdPrefix) {
        redisService.deleteHashByPrefix(imei, cmdPrefix);
        return commandRecordService.deleteCacheCmd(imei, cmdPrefix) > 0 ? true : false;
    }

    @Override
    public boolean setAppDisable(DeviceInfo deviceInfo, String packageName, int appFlag, List<AppDisableTimeDto> appDisableTimeDtos) {
        if (deviceInfo == null) {
            return false;
        }
        deleteCacheCmd(deviceInfo.getImei(), Constants.APP_DISABLE.concat("-").concat(packageName));
        appDisableTimeService.deleteAppDisableByDeviceIdAndPackageName(deviceInfo.getDeviceId(), packageName);
        updateAppDisableFlag(deviceInfo.getDeviceId(), packageName, DeviceAppFlagEnum.getDeviceAppFlagEnum(appFlag).getStayState());
        List<MqAppDisableTime> mqAppDisableTimes = new ArrayList<>();
        if (appDisableTimeDtos != null && appDisableTimeDtos.size() > 0) {
            List<AppDisableTime> appDisableTimes = new ArrayList<>();
            for (AppDisableTimeDto appDisableTimeDto : appDisableTimeDtos) {
                //一下为数据库对象的转换
                AppDisableTime appDisableTime = new AppDisableTime();
                appDisableTime.setDeviceId(deviceInfo.getDeviceId());
                appDisableTime.setPackageName(packageName);
                appDisableTime.setFlag(appDisableTimeDto.getActivation());
                appDisableTime.setStartTime(appDisableTimeDto.getStartTime());
                appDisableTime.setEndTime(appDisableTimeDto.getEndTime());
                appDisableTime.setCycle(appDisableTimeDto.getCycle());
                appDisableTime.setCreateTime(new Date().getTime());
                appDisableTimes.add(appDisableTime);
                //以下是发往设备的对象的转换
                MqAppDisableTime mqAppDisableTime = new MqAppDisableTime();
                mqAppDisableTime.setStartTime(appDisableTimeDto.getStartTime());
                mqAppDisableTime.setEndTime(appDisableTimeDto.getEndTime());
                mqAppDisableTime.setCycle(appDisableTimeDto.getCycle());
                mqAppDisableTime.setActivation(appDisableTimeDto.getActivation());
                mqAppDisableTimes.add(mqAppDisableTime);
            }
            appDisableTimeService.saveBatch(appDisableTimes);
        }
        MqAppDisable mqAppDisable = new MqAppDisable();
        mqAppDisable.setImei(deviceInfo.getImei());
        mqAppDisable.setCommandNumber(CommandNumberUtils.generateCommandNumber(redisService, deviceInfo.getImei()));
        mqAppDisable.setPackageName(packageName);
        mqAppDisable.setFlag(appFlag);
        mqAppDisable.setMqAppDisableTime(mqAppDisableTimes);
        mqAppDisable.setGroupNum(mqAppDisableTimes.size());
        boolean online = commandSendUtils.deviceOnline(deviceInfo.getImei());
        commandSendUtils.appDisable(mqAppDisable, online, Constants.WX_COMMAND_USER_ID, false);
        return true;
    }

    @Override
    public DeviceFlag queryDeviceSwitch(Integer deviceId) {
        return deviceFlagService.queryDeviceSwitch(deviceId);
    }

    @Override
    public QueryAppDisAbleStateDto queryAppDisAbleState(Integer deviceId, String packageName) {
        return deviceAppMapper.queryAppDisAbleState(deviceId, packageName);
    }

}
